"""
验证器
    封装了很多的验证器 你可以在开发事件时使用MethodScript进行判断 每个方法的参数都是 EventEntiys
"""
from typing import List

from api.charts.ChartGenerate import ChartGenerate
from basic.entiys.charts.BaseCharts import BaseCharts
from framework.syntacticSugar.EventEntiys import EventEntiys


class ChartTypeEnum:
    SELF = "SELF"  # EventEntiys.self
    INVOLVER = "INVOLVER"  # EventEntiys.involver
    BOTH = "SELF/INVOLVER"  # EventEntiys.involver and EventEntiys.self
    ALL = "SELF/INVOLVER/ANTHOR"  # EventEntiys.involver and EventEntiys.self and EventEntiys.anthor


def getChartIntanceByChartTypeEnum(e: EventEntiys, chartType: ChartTypeEnum) -> List[BaseCharts]:
    """
    获取 某个事件中扮演指定类型角色的角色列表
    :param e: 某个事件的event_entiy
    :param chartType: 角色的类型
    :return:
    """

    def get():
        nonlocal e, chartType
        type_chart = chartType
        if type_chart == ChartTypeEnum.SELF:
            assert e.self is not None
            return [e.self]

        elif type_chart == ChartTypeEnum.INVOLVER:
            assert e.involver is not None
            return [e.involver]
        elif type_chart == ChartTypeEnum.BOTH:
            assert e.self is not None and e.involver is not None
            return [e.self, e.involver]
        else:
            return [e.self, e.involver] + e.anther

    list_ = get()
    list_ = [ChartGenerate.getCharacter_name(i) for i in list_]
    return list_


class ChartsValidate:
    #FIXME has 和 in 的代码复用太高！
    @staticmethod
    def has_injail(e, chartType) -> bool:
        charts = getChartIntanceByChartTypeEnum(e, chartType)
        for i in charts:
            if i.fields.in_jail == "True":
                return True
        return False

    @staticmethod
    def is_injail(e, chartType) -> bool:
        """
        判断 在 e 中角色的参与类型为 chartType 是否  都在监狱中
        """
        charts = getChartIntanceByChartTypeEnum(e, chartType)
        for i in charts:
            if i.fields.in_jail != "True":
                return False
        return True

    @staticmethod
    def has_king(e, chartType) -> bool:
        """
        判断 在 e 中角色的参与类型为 chartType 是否 存在 为领主权能
        """
        charts = getChartIntanceByChartTypeEnum(e, chartType)
        for i in charts:
            if i.fields.authority == "LordAuth":  # is_king 会默认到 default的领主权能
                return True
        return False

    @staticmethod
    def is_king(e: EventEntiys, chartType: ChartTypeEnum) -> bool:
        """
        判断 在 e 中角色的参与类型为 chartType 是否 全部 为领主权能
        :param e: 某个事件的 EventEntiys 对象
        :param chartType: 参与角色的 ChartTypeEnum
        :return:
        """
        charts = getChartIntanceByChartTypeEnum(e, chartType)
        for i in charts:
            if i.fields.authority != "LordAuth":  # is_king 会默认到 default的领主权能
                return False  # 因为有不是领主的 所以返回None
        return True

    @staticmethod
    def is_self_live(e: EventEntiys) -> bool:
        """
        判断self角色是否存活
        :param e:
        :return:
        """
        return not e.self.fields.is_die

    @staticmethod
    def is_all_live(e: EventEntiys) -> bool:
        """
        判断 参与事件的角色 是否都存活
        :param e:
        :return:
        """

        def inner():
            for i in e.anther:
                if isinstance(i, str):
                    chart = ChartGenerate.getCharacter_name(i)
                    if chart.fields.is_die:
                        return False
            return True

        return ChartsValidate.is_self_live(e) and ChartsValidate.is_involver_live(e) and inner()

    @staticmethod
    def is_involver_live(e) -> bool:
        """
        判断 被动方 是否存活
        :param e:
        :return:
        """
        return not e.involver.fields.is_die
